using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Uantek.Device.Communication.Configuration;
using Uantek.Device.Communication.Jobs;
using Uantek.Device.Communication.Services;
using Uantek.Device.Communication.Services.Interfaces;
using Uantek.Device.Communication.Utilities;

namespace Uantek.Device.Communication
{
    /// <summary>
    /// 设备通信模块服务注册扩展
    /// </summary>
    public static class ServiceExtensions
    {
        /// <summary>
        /// 添加设备通信服务
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configuration">配置</param>
        /// <returns></returns>
        public static IServiceCollection AddDeviceCommunication(this IServiceCollection services, IConfiguration configuration)
        {
            // 注册配置
            var configSection = configuration.GetSection("DeviceCommunication");
            var config = new DeviceCommunicationConfig();
            configSection.Bind(config);
            services.Configure<DeviceCommunicationConfig>(configSection);
            services.AddSingleton(config);

            // 注册核心服务
            services.AddDeviceCommunicationServices(config);

            // 注册任务调度
            services.AddDeviceCommunicationJobs(config);

            // 注册工具类
            services.AddDeviceCommunicationUtilities(config);

            return services;
        }

        /// <summary>
        /// 添加设备通信服务（使用默认配置）
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configureOptions">配置选项</param>
        /// <returns></returns>
        public static IServiceCollection AddDeviceCommunication(this IServiceCollection services, Action<DeviceCommunicationConfig>? configureOptions = null)
        {
            var config = new DeviceCommunicationConfig();
            configureOptions?.Invoke(config);

            services.AddSingleton(config);
            services.Configure<DeviceCommunicationConfig>(options =>
            {
                configureOptions?.Invoke(options);
            });

            // 注册核心服务
            services.AddDeviceCommunicationServices(config);

            // 注册任务调度
            services.AddDeviceCommunicationJobs(config);

            // 注册工具类
            services.AddDeviceCommunicationUtilities(config);

            return services;
        }

        /// <summary>
        /// 注册核心服务
        /// </summary>
        private static IServiceCollection AddDeviceCommunicationServices(this IServiceCollection services, DeviceCommunicationConfig config)
        {
            if (!config.Enabled)
            {
                return services;
            }

            // 注册设备通信服务
            services.AddSingleton<IDeviceCommunicationService, DeviceCommunicationService>();

            // 注册数据收集服务
            if (config.DataCollection.Enabled)
            {
                services.AddSingleton<IDataCollectionService, DataCollectionService>();
            }

            // 注册MQTT发布服务
            if (config.Mqtt.Enabled)
            {
                services.AddSingleton<IMqttPublishService, MqttPublishService>();
            }

            // 注册后台服务
            services.AddHostedService<DeviceCommunicationBackgroundService>();

            return services;
        }

        /// <summary>
        /// 注册任务调度
        /// </summary>
        private static IServiceCollection AddDeviceCommunicationJobs(this IServiceCollection services, DeviceCommunicationConfig config)
        {
            if (!config.JobScheduling.Enabled)
            {
                return services;
            }

            // 注册设备通信任务
            if (config.JobScheduling.DeviceCommunicationJob.Enabled)
            {
                services.AddSingleton<DeviceCommunicationJob>();
                services.AddHostedService<DeviceCommunicationJobHostedService>();
            }

            // 注册数据持久化任务
            if (config.JobScheduling.DataPersistenceJob.Enabled)
            {
                services.AddSingleton<DataPersistenceJob>();
                services.AddHostedService<DataPersistenceJobHostedService>();
            }

            return services;
        }

        /// <summary>
        /// 注册工具类
        /// </summary>
        private static IServiceCollection AddDeviceCommunicationUtilities(this IServiceCollection services, DeviceCommunicationConfig config)
        {
            // 注册数据表达式计算器
            services.AddSingleton<IDataExpressionEvaluator, DataExpressionEvaluator>();

            // 注册Redis数据管理器
            services.AddSingleton<IRedisDataManager, RedisDataManager>();

            return services;
        }
    }

    /// <summary>
    /// 设备通信后台服务
    /// </summary>
    public class DeviceCommunicationBackgroundService : BackgroundService
    {
        private readonly ILogger<DeviceCommunicationBackgroundService> _logger;
        private readonly IServiceProvider _serviceProvider;
        private readonly DeviceCommunicationConfig _config;

        public DeviceCommunicationBackgroundService(
            ILogger<DeviceCommunicationBackgroundService> logger,
            IServiceProvider serviceProvider,
            DeviceCommunicationConfig config)
        {
            _logger = logger;
            _serviceProvider = serviceProvider;
            _config = config;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            try
            {
                _logger.LogInformation("设备通信后台服务启动");

                using var scope = _serviceProvider.CreateScope();

                // 启动设备通信服务
                var deviceCommunicationService = scope.ServiceProvider.GetService<IDeviceCommunicationService>();
                if (deviceCommunicationService != null)
                {
                    var startResult = await deviceCommunicationService.StartAsync();
                    if (startResult.Success)
                    {
                        _logger.LogInformation("设备通信服务启动成功");
                    }
                    else
                    {
                        _logger.LogError($"设备通信服务启动失败: {startResult.Message}");
                    }
                }

                // 连接MQTT服务器
                var mqttService = scope.ServiceProvider.GetService<IMqttPublishService>();
                if (mqttService != null && _config.Mqtt.Enabled)
                {
                    var clientId = $"{_config.Mqtt.ClientIdPrefix}_{Environment.MachineName}_{DateTime.Now.Ticks}";
                    var connectResult = await mqttService.ConnectAsync(
                        _config.Mqtt.ServerAddress,
                        _config.Mqtt.Port,
                        clientId,
                        _config.Mqtt.Username,
                        _config.Mqtt.Password);

                    if (connectResult.Success)
                    {
                        _logger.LogInformation("MQTT服务连接成功");
                        mqttService.SetDefaultTopicPrefix(_config.Mqtt.DefaultTopicPrefix);
                    }
                    else
                    {
                        _logger.LogError($"MQTT服务连接失败: {connectResult.Message}");
                    }
                }

                // 等待取消信号
                await Task.Delay(Timeout.Infinite, stoppingToken);
            }
            catch (OperationCanceledException)
            {
                _logger.LogInformation("设备通信后台服务正在停止");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设备通信后台服务执行失败");
            }
        }

        public override async Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("设备通信后台服务停止中");

            try
            {
                using var scope = _serviceProvider.CreateScope();

                // 停止设备通信服务
                var deviceCommunicationService = scope.ServiceProvider.GetService<IDeviceCommunicationService>();
                if (deviceCommunicationService != null)
                {
                    await deviceCommunicationService.StopAsync();
                }

                // 断开MQTT连接
                var mqttService = scope.ServiceProvider.GetService<IMqttPublishService>();
                if (mqttService != null)
                {
                    await mqttService.DisconnectAsync();
                }

                _logger.LogInformation("设备通信后台服务已停止");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "停止设备通信后台服务时发生错误");
            }

            await base.StopAsync(cancellationToken);
        }
    }

    /// <summary>
    /// 设备通信服务配置扩展
    /// </summary>
    public static class DeviceCommunicationConfigExtensions
    {
        /// <summary>
        /// 验证配置
        /// </summary>
        /// <param name="config">配置对象</param>
        /// <returns>验证结果</returns>
        public static (bool IsValid, List<string> Errors) Validate(this DeviceCommunicationConfig config)
        {
            var errors = new List<string>();

            // 验证设备设置
            if (config.Device.DefaultConnectionTimeout < 1000 || config.Device.DefaultConnectionTimeout > 60000)
            {
                errors.Add("设备连接超时时间必须在1000-60000毫秒之间");
            }

            if (config.Device.MaxRetryCount < 0 || config.Device.MaxRetryCount > 10)
            {
                errors.Add("最大重试次数必须在0-10之间");
            }

            // 验证数据收集设置
            if (config.DataCollection.Enabled)
            {
                if (config.DataCollection.DefaultInterval < 100 || config.DataCollection.DefaultInterval > 3600000)
                {
                    errors.Add("数据收集间隔必须在100-3600000毫秒之间");
                }

                if (config.DataCollection.BatchSize < 1 || config.DataCollection.BatchSize > 10000)
                {
                    errors.Add("批处理大小必须在1-10000之间");
                }
            }

            // 验证MQTT设置
            if (config.Mqtt.Enabled)
            {
                if (string.IsNullOrWhiteSpace(config.Mqtt.ServerAddress))
                {
                    errors.Add("MQTT服务器地址不能为空");
                }

                if (config.Mqtt.Port < 1 || config.Mqtt.Port > 65535)
                {
                    errors.Add("MQTT端口必须在1-65535之间");
                }

                if (config.Mqtt.QosLevel < 0 || config.Mqtt.QosLevel > 2)
                {
                    errors.Add("MQTT QoS等级必须在0-2之间");
                }
            }

            // 验证任务调度设置
            if (config.JobScheduling.Enabled)
            {
                if (config.JobScheduling.DeviceCommunicationJob.Enabled)
                {
                    if (string.IsNullOrWhiteSpace(config.JobScheduling.DeviceCommunicationJob.CronExpression))
                    {
                        errors.Add("设备通信任务Cron表达式不能为空");
                    }
                }

                if (config.JobScheduling.DataPersistenceJob.Enabled)
                {
                    if (string.IsNullOrWhiteSpace(config.JobScheduling.DataPersistenceJob.CronExpression))
                    {
                        errors.Add("数据持久化任务Cron表达式不能为空");
                    }
                }
            }

            return (errors.Count == 0, errors);
        }

        /// <summary>
        /// 获取配置摘要
        /// </summary>
        /// <param name="config">配置对象</param>
        /// <returns>配置摘要</returns>
        public static string GetSummary(this DeviceCommunicationConfig config)
        {
            var summary = new System.Text.StringBuilder();
            summary.AppendLine($"设备通信模块: {(config.Enabled ? "启用" : "禁用")}");
            summary.AppendLine($"数据收集: {(config.DataCollection.Enabled ? "启用" : "禁用")}");
            summary.AppendLine($"MQTT发布: {(config.Mqtt.Enabled ? "启用" : "禁用")}");
            summary.AppendLine($"任务调度: {(config.JobScheduling.Enabled ? "启用" : "禁用")}");
            summary.AppendLine($"性能监控: {(config.Performance.EnablePerformanceMonitoring ? "启用" : "禁用")}");
            return summary.ToString();
        }
    }

    /// <summary>
    /// 设备通信任务后台服务
    /// </summary>
    public class DeviceCommunicationJobHostedService : BackgroundService
    {
        private readonly ILogger<DeviceCommunicationJobHostedService> _logger;
        private readonly DeviceCommunicationJob _job;
        private readonly DeviceCommunicationConfig _config;

        public DeviceCommunicationJobHostedService(
            ILogger<DeviceCommunicationJobHostedService> logger,
            DeviceCommunicationJob job,
            DeviceCommunicationConfig config)
        {
            _logger = logger;
            _job = job;
            _config = config;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _logger.LogInformation("设备通信任务后台服务启动");

            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    await _job.Execute(null!);
                    
                    // 简单的定时执行，实际项目中可以解析Cron表达式
                    await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
                }
                catch (OperationCanceledException)
                {
                    break;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "设备通信任务执行失败");
                    await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
                }
            }

            _logger.LogInformation("设备通信任务后台服务停止");
        }
    }

    /// <summary>
    /// 数据持久化任务后台服务
    /// </summary>
    public class DataPersistenceJobHostedService : BackgroundService
    {
        private readonly ILogger<DataPersistenceJobHostedService> _logger;
        private readonly DataPersistenceJob _job;
        private readonly DeviceCommunicationConfig _config;

        public DataPersistenceJobHostedService(
            ILogger<DataPersistenceJobHostedService> logger,
            DataPersistenceJob job,
            DeviceCommunicationConfig config)
        {
            _logger = logger;
            _job = job;
            _config = config;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _logger.LogInformation("数据持久化任务后台服务启动");

            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    await _job.Execute(null!);
                    
                    // 简单的定时执行，实际项目中可以解析Cron表达式
                    await Task.Delay(TimeSpan.FromMinutes(10), stoppingToken);
                }
                catch (OperationCanceledException)
                {
                    break;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "数据持久化任务执行失败");
                    await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
                }
            }

            _logger.LogInformation("数据持久化任务后台服务停止");
        }
    }
}